<?php

namespace App\Services;

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use EasyWeChat\Factory;

class UserService
{
    public $msg = '服务繁忙，请稍后再试';
    /**
     *
     * 注册领取vip
     * @param $uid
     * @return bool
     */
    public function receiveVip($uid): bool
    {
        try {
            \DB::beginTransaction();
            $this->addUserVip($uid, 3, 1, getOrderNo($uid, 3));
            \DB::commit();
        }catch (\Exception $exception){
            \DB::rollBack();
            return false;
        }
        return true;
    }

    /**
     * 用户签到
     * @param $uid
     * @return int
     */
    public function sign($uid) :int
    {
        $lastSign = \DB::table('users_sign')->where('uid', $uid)->orderBy('id', 'desc')->first();
        if( $lastSign && $lastSign->date == date('Y-m-d', strtotime('-1 day', time())) && $lastSign->count < 7 ){
            // 持续签到
            $continueNum = $lastSign->count+1;//连续签到天数
        }else{
            $continueNum = 1;
        }
//        获取签到奖品
        $data = $this->getSignLot($continueNum);
        $signData = [
            'uid' => $uid,
            'date' => date('Y-m-d'),
            'count' => $continueNum,
            'lot_type' => $data['type'],
            'lot_value' => $data['value'],
            'status' => $data['isCurrent'],
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        try {
            DB::beginTransaction();
            DB::table('users_sign')->insert($signData);
            if( $data['isCurrent'] == 1 ){
//                立即到账：返现金
                $this->userBalanceUpdate($uid, $data['value'], 3, 0, 1);
                //类型：
                //1-订单结算,
                //2-微信手续费，
                //3-订单返佣，
                //4-上级返佣，
                //5-平台提现，
                //6-用户提现平台手续费，
                //7-会费入账，
                //8-营销支出，
                //9-平台充值，
                $log = [
                    ['type'=>8, 'type_value'=>'营销支出', 'title'=>'用户签到', 'order_no'=>getOrderNo($uid, 5), 'amount'=>$data['value'], 'created_at'=>date('Y-m-d H:i:s')],
                ];
//                插入平台对账单
                DB::table('platform_balance_log')->insert($log);
            }

            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return 0;
        }


        return $continueNum;
    }

    /**
     * 领取奖品
     * @param $uid
     * @param $id
     * @return bool
     */
    public function receiveLot($uid, $id):bool
    {
        $data = DB::table('users_sign')->where('id', $id)->where('uid', $uid)->first();
        if( !$data || $data->status == 1 ){
            $this->msg = '已领取';
            return false;
        }
        try {
            DB::beginTransaction();
            DB::table('users_sign')->where('id', $id)->where('status', 0)->update(['status'=>1, 'updated_at'=>getDt()]);
            if( $data->lot_type == 1 ){
//                立即到账：返现金
                $this->userBalanceUpdate($uid, $data->lot_value, 3, 0, 1);
                $log = [
                    ['type'=>8, 'type_value'=>'营销支出', 'title'=>'用户签到', 'order_no'=>getOrderNo($uid, 5), 'amount'=>$data->lot_value, 'created_at'=>getDt()],
                ];
//                插入平台对账单
                DB::table('platform_balance_log')->insert($log);
            }else{
//                vip
                $this->addUserVip($uid, $data->lot_value, 2, getOrderNo($uid, 3));
            }

            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return 0;
        }

        $this->msg = $data->lot_type ==1 ? "恭喜您获得现金{$data->lot_value}元" : "恭喜您获得VIP{$data->lot_value}天";

        return true;
    }

    /**
     * 领取邀请返佣
     * @param $uid
     * @return bool
     */
    public function receiveInviteLot($uid):bool
    {
        $data = DB::table('users_balance_logs')->where('uid', $uid)->where('status', 0)->where('type', 2)->get();
        if( !$data  ){
            $this->msg = '暂无需要领取的邀请奖金';
            return false;
        }

        $da = [];
        try {
            DB::beginTransaction();
            foreach ($data as $datum) {
                DB::table('users')->where('id',  $uid)->increment('balance', $datum->money);
                DB::table('users_balance_logs')->where('id', $datum->id)->update(['status'=>1, 'updated_at'=>getDt()]);
                $da[] = ['type'=>4, 'type_value'=>'上级返佣', 'title'=>$datum->title, 'order_no'=>getOrderNo($datum->uid, 5), 'transaction_no'=>$datum->transaction_no, 'amount'=>config('app.parent_amount'), 'created_at'=>getDt(), 'updated_at'=>getDt()];
            }
            //平台对账明细添加
            DB::table('platform_balance_log')->insert($da);

            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return false;
        }

        return true;
    }

    /**
     * 饭点打卡参与
     * @param $uid
     * @param int $amount
     * @return bool
     */
    public function joinMeals($uid, int $amount):bool
    {
        $user = DB::table('users')->where('id', $uid)->first();
        if( !$user || $user->balance < $amount ){
            $this->msg = '用户品鉴金不足';
            return false;
        }

        $meals = DB::table('meals')->where('date', date('Y-m-d', strtotime('+1 day', time())))->first();
        if( !$meals ){
            $this->msg = '活动还未开启';
            return false;
        }

        if( DB::table('meals_join')->where('uid', $uid)->where('date', date('Y-m-d', strtotime('+1 day', time())))->count() ){
            $this->msg = '无法重复参与活动';
            return false;
        }

        try {
            DB::beginTransaction();
//            消耗品鉴金
            $this->userBalanceUpdate($uid, -$amount, 5, 0, 1);
//            添加打卡记录
            DB::table('meals_join')->insert([
                'uid' => $uid,
                'amount' => $amount,
                'date' => date('Y-m-d', strtotime('+1 day', time())),
                'created_at' => date('Y-m-d H:i:s'),
            ]);
//            增加奖金池
            DB::table('meals')->where('id', $meals->id)->update([
                'user_amount'=>DB::raw('user_amount+'.$amount),
                'join_num'=>DB::raw('join_num+1'),
                'updated_at'=>getDt(),
            ]);

            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return 0;
        }

        return true;
    }

    /**
     * 打卡签到
     * @param $uid
     * @return bool
     */
    public function signMeals($uid):bool
    {
        $join = DB::table('meals_join')->where('uid', $uid)->where('date', date('Y-m-d'))->first();
        if( !$join ){
            $this->msg = '您未参与今天的活动无法打卡';
            return false;
        }
        if( $join->is_sign == 1 ){
            $this->msg = '您已打卡成功';
            return false;
        }
        try {
            DB::beginTransaction();
//            更新签到标记
            DB::table('meals_join')->where('uid', $uid)->where('date', date('Y-m-d'))->update(['is_sign'=>1, 'updated_at'=>date('Y-m-d H:i:s')]);
//            增加奖金池
            DB::table('meals')->where('date', date('Y-m-d'))->update([
                'sign_amount'=>DB::raw('sign_amount+'.$join->amount),
                'sign_num'=>DB::raw('sign_num+1'),
                'updated_at'=>getDt(),
            ]);

            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return 0;
        }

        return true;
    }

    /**
     * 订单满5领取vip
     * @param $uid
     * @return bool
     */
    public function userFiveOrderLot($uid):bool
    {
        $count = \DB::table('users_orders')->where('uid', $uid)->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])->where('status', 50)->count();
        if( $count >= 5 ){
//            查看是否已领
            $count = DB::table('users_vip_receive_log')->where([
                'uid'   => $uid,
                'type'   => 3
            ])->where('created_at', '>', Carbon::now()->startOfWeek())->count();
            if( $count ){
                $this->msg = '您本周已领取无法重复领取';
                return false;
            }
            try {
                DB::beginTransaction();
                //领取vip
                $this->addUserVip($uid, 2, 3, getOrderNo($uid, 3));
                DB::commit();
            }catch (\Exception $exception){
                DB::rollBack();
                return 0;
            }
            return true;
        }else{
            $this->msg = '您本周结算订单数还未满5单';
            return false;
        }
    }

    /**
     * 为用户添加vip
     * @param $uid
     * @param $num
     * @param $type
     * @param $tranNo
     * @param $amount
     * @param $status
     */
    public static function addUserVip($uid, $num, $type, $tranNo='', $amount = 0, $status=2){
        \DB::table('users_vip_receive_log')->insert([
            'type'  => $type,
            'uid'  => $uid,
            'num'   => $num,
            'transaction_no'   => $tranNo,
            'amount'   => $amount,
            'status'   => $status,
            'created_at'   => getDt(),
            'updated_at'   => getDt(),
        ]);
        $user = DB::table('users')->where('id', $uid)->select(['vip_status', 'vip_overdue'])->first();
        if( $user->vip_status == 1 ){
            DB::table('users')->where('id', $uid)->update(['vip_overdue'=>date('Y-m-d H:i:s', strtotime('+'.$num.' day', strtotime($user->vip_overdue))), 'updated_at'=>date('Y-m-d H:i:s'), 'vip_status'=>1]);
        }else{
            DB::table('users')->where('id', $uid)->update(['vip_overdue'=>date('Y-m-d H:i:s', strtotime('+'.$num.' day', time())), 'updated_at'=>date('Y-m-d H:i:s'), 'vip_status'=>1]);
        }
    }

    /**
     * 用户余额变动操作
     * @param $uid
     * @param $amount
     * @param $type
     * @param $fromId
     * @param $status
     * @param $transactionNo
     */
    public static function userBalanceUpdate($uid, $amount, $type, $fromId, $status, $transactionNo=''){
        if( $status == 1 ){
            //即刻到账，用户余额变动
            DB::table('users')->where('id', $uid)->increment('balance', $amount);
        }

//        余额变动记录添加  0-提现，1-下单返现，2-下级下单返,3-签到返现，4-打卡活动返现，5-参与打卡消耗,6-提现失败退回
        $arr = ['提现兑换','点餐入账','下级点餐返','签到返现','活动入账','活动消费', '提现失败退回'];
        $arr1 = ['提现兑换','点餐入账','下级点餐返','签到返现','活动入账','活动消费', '提现失败退回'];
        $type_value = $arr[$type];
        if( $type == 1 || $type == 2 ){
            $order = DB::table('users_orders')->where('id', $fromId)->select(['store_title', 'good_comment_type', 'max_money', 'return_money'])->first();
            $title = $order->store_title.' '.($order->good_comment_type?config('app.good_comment_type')[$order->good_comment_type]:'').' '."满{$order->max_money}返{$order->return_money}";
        }else{
            $title = $arr1[$type];
        }

        $data = [
            'uid' => $uid,
            'type' => $type,
            'type_value' => $type_value,
            'title' => $title,
            'money' => abs($amount),
            'order_no' => getOrderNo($uid, 4),
            'transaction_no' => $transactionNo,
            'from_order_id' => $fromId,
            'status' => $status,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        DB::table('users_balance_logs')->insert($data);
    }

    /**
     * 获取签到奖品
     * @param $num
     * @return array
     */
    private function getSignLot($num):array
    {
        $type = 1;//奖品类型:1返现金 2-vip
        $value = '';//奖品值
        $isCurrent = 1;//是否直接到账0-否，1-是
        switch ($num){
            case 1:
            case 2:
            case 4:
            case 5:
            case 6: $type = 1;$value = mt_rand(1, 3) / 100;break;
            case 3: $type = 2;$value = 1;$isCurrent=0;break;
            case 7:
                $isCurrent=0;
                $rand = mt_rand(1, 100);
                if( $rand <= 95 ){
                    $type = 2;$value = 2;
                }else if( $rand <= 99 ){
                    $type = 1;$value = 2;
                }else{
                    $type = 1;$value = 6;
                }
                break;
            default:
        }
        return ['type'=>$type, 'value'=>$value, 'isCurrent'=>$isCurrent];
    }

    /**
     * 发送小程序模板消息
     *
     * @param [type] $uid
     * @param [type] $type
     * @param [type] $title
     * @return void
     */
    public static function sendMiniSoftMsg($openid, $type, $page, $data1){
        $config = config('wechat.mini_program.default');
        $app = Factory::miniProgram($config);

        $messages = config('app.subscribe_message');
        $id = $messages[$type];
        $data = [
            'template_id' => $id, // 所需下发的订阅模板id
            'touser' => $openid,     // 接收者（用户）的 openid
            'page' => $page,       // 点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转。
            'data' => $data1,// 模板内容，格式形如 { "key1": { "value": any }, "key2": { "value": any } }
        ];
        // InterfaceLog($data, '小程序订阅消息发送日志:', 1);
        $res = $app->subscribe_message->send($data);
        // InterfaceLog($res, '小程序订阅消息发送日志res:', 1);
        if( isset($res['errmsg']) && $res['errmsg'] == 'ok' ){

        }else{
            //失败
            InterfaceLog($data, '小程序订阅消息发送失败日志:'.(isset($res['errmsg'])?$res['errmsg']:'无响应'), 2);
        }
        
    }

}